package com.gzx.plugin.tjzy.modular.call.receipt.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.github.benmanes.caffeine.cache.Cache;
import com.gzx.plugin.tjzy.modular.caffeine.UserCaffeine;
import com.gzx.plugin.tjzy.modular.call.ht.entity.GzxHtVoiceText;
import com.gzx.plugin.tjzy.modular.call.receipt.entity.GzxHtCallReceipt;
import com.gzx.plugin.tjzy.modular.call.receipt.mapper.GzxHtCallReceiptMapper;
import com.gzx.plugin.tjzy.modular.call.receipt.service.GzxHtCallReceiptService;
import com.gzx.plugin.tjzy.modular.call.scripts.config.CallScriptInitializationConfig;
import com.gzx.plugin.tjzy.modular.qianwen.service.IntentPromptService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import vip.xiaonuo.common.cache.CommonCacheOperator;
import vip.xiaonuo.common.consts.GzxTenantConstant;
import vip.xiaonuo.common.kafka.KafkaMessageProducer;
import vip.xiaonuo.common.kafka.KafkaTopicConstant;
import vip.xiaonuo.common.sses.consts.SseMsgTypeConstant;
import vip.xiaonuo.common.sses.entity.SseMessage;
import vip.xiaonuo.common.sses.util.CommonSseUtil;
import vip.xiaonuo.common.util.CommonCryptogramUtil;
import vip.xiaonuo.common.util.CommonDateUtil;
import vip.xiaonuo.common.util.CommonExcelUtil;
import vip.xiaonuo.common.util.CommonSleepUtil;

import java.util.List;
import java.util.Map;

/**
 * @author zjt
 * @description
 * @date 2025/3/28 17:52
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class GzxHtCallReceiptServiceImpl implements GzxHtCallReceiptService {

	private final GzxHtCallReceiptMapper htCallReceiptMapper;

	private final IntentPromptService intentPromptService;

	private final KafkaMessageProducer kafkaMessageProducer;

	private final CommonCacheOperator cacheOperator;

	private final CommonSseUtil sseUtil;

	private final CallScriptInitializationConfig callScriptInitializationConfig;

	private final Cache<String, String> callUserCache;

	private final UserCaffeine userCaffeine;

	/**
	 * 导入话单到Kafka
	 *
	 * @param multipartFile
	 */
	@Override
	public void sendReceiptToKafka(MultipartFile multipartFile) {
		List<GzxHtCallReceipt> htCallReceiptList = CommonExcelUtil.importExcel(multipartFile, GzxHtCallReceipt.class);
		if (CollectionUtil.isNotEmpty(htCallReceiptList)) {
			for (GzxHtCallReceipt htCallReceipt : htCallReceiptList) {
				kafkaMessageProducer.sendMessage(KafkaTopicConstant.CALL_RECEIPT_TOPIC, htCallReceipt.getCallId(),
						JSON.toJSONString(htCallReceipt));
			}
		}
	}

	/**
	 * 收到恒天话单
	 */
	@Override
	@DS("tjzy-async")
	public void receiveCallReceipt(String reqStr) {
		long start = System.currentTimeMillis();
		log.info("恒天话单回调数据：{}", reqStr.length());
		GzxHtCallReceipt htCallReceipt = JSON.parseObject(reqStr, GzxHtCallReceipt.class);
		htCallReceipt.setId(IdUtil.getSnowflakeNextId());
		htCallReceipt.setCallee(CommonCryptogramUtil.doSm1AesEncrypt(htCallReceipt.getCallee()));
		htCallReceipt.setCreateTime(CommonDateUtil.getCurrentTimeStr());
		int rowNum = htCallReceiptMapper.insertIgnore(htCallReceipt);
		if (rowNum > 0) {
			kafkaMessageProducer.sendMessage(KafkaTopicConstant.CALL_RECEIPT_TOPIC, htCallReceipt.getCallId(),
					JSON.toJSONString(htCallReceipt));
			// 发送到消息队列（数据看板专用）
			kafkaMessageProducer.sendMessage(KafkaTopicConstant.DATA_BOARD_TOPIC, htCallReceipt.getCallId(),
					JSON.toJSONString(htCallReceipt));
		}
		log.info("恒天话单回调数据 used：{}", (System.currentTimeMillis() - start));
	}

	/**
	 * 接收语音转文字的对象
	 *
	 * @param reqBody
	 */
	@Override
	public void receiveVoiceText(String reqBody) {
		log.info("收到恒天回传的语音文字：{}", reqBody == null ? 0 : reqBody.length());
		GzxHtVoiceText htVoiceText = JSON.parseObject(reqBody, GzxHtVoiceText.class);
		if (htVoiceText != null) {
			htVoiceText.setContent(htVoiceText.getContent().replaceAll("\\s", ""));
			// 发送到消息队列
			kafkaMessageProducer.sendMessage("voice-topic", htVoiceText.getCallId() + "|" + htVoiceText.getSessionNo(),
					JSON.toJSONString(htVoiceText));
			Thread.startVirtualThread(() -> {
				sendText(htVoiceText);
			});
		}
	}

	/**
	 * 设置闪信号码
	 *
	 * @param fmPhone
	 */
	@Override
	public void setFmPhone(String fmPhone) {
		cacheOperator.setCatchString("FM_PHONE", fmPhone);
	}

	private void sendText(GzxHtVoiceText htVoiceText) {
		if (StringUtils.isNotEmpty(htVoiceText.getCallId())) {
			// 去redis获取对应的LoginId
			String loginId = getLoginIdByCallIdFromCache(htVoiceText.getCallId());
			if (StringUtils.isNotEmpty(loginId)) {
				sseUtil.sendMessageToUser(loginId,
						new SseMessage(SseMsgTypeConstant.VOICE_TEXT, JSON.toJSONString(htVoiceText)));
				if (htVoiceText.getSpeakerRole() == 1) {
					// 发送推荐话术
					sendCallScripts(loginId, htVoiceText);
				}
			}
		}
	}

	private String getLoginIdByCallIdFromCache(String callId) {
		String userId = callUserCache.getIfPresent(callId);
		if (StringUtils.isBlank(userId)) {
			for (int i = 0; i <= 5; i++) {
				if (cacheOperator.isKeyExists("CallId_" + callId)) {
					userId = cacheOperator.getCatchString("CallId_" + callId);
					callUserCache.put(callId, userId);
					break;
				} else {
					CommonSleepUtil.sleep500();
				}
			}
		}
		return userId;
	}

	private List<String> getCallScripts(String voiceText) {
		String intent = intentPromptService.analyzeIntent(voiceText);
		return StringUtils.isNotBlank(intent) ? callScriptInitializationConfig.getCallScriptMap(intent) : List.of();
	}

	private void sendCallScripts(String loginId, GzxHtVoiceText htVoiceText) {
		// 判断权限是否需要推荐话术
		Map<String, JSONObject> userMap = userCaffeine.getUserMapByTenantId(GzxTenantConstant.GZX_TENANT_ID);
		if (userMap.containsKey(loginId)) {
			JSONObject userJson = userMap.get(loginId);
			String positionLevel = userJson.getStr("positionLevel");
			if (StringUtils.isNotBlank(positionLevel) && "C1".equals(positionLevel)) {
				// 获取推荐话术
				List<String> callScriptsList = getCallScripts(htVoiceText.getContent());
				if (CollectionUtil.isNotEmpty(callScriptsList)) {
					sseUtil.sendMessageToUser(loginId, new SseMessage(SseMsgTypeConstant.CALL_SCRIPTS,
							JSON.toJSONString(Map.of(htVoiceText.getChatTime(), callScriptsList))));
				}
			}
		}
	}
}
